/**
 * 
 */
package com.jxc.service.impl;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.hibernate.Hibernate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jxc.dao.BaseDaoI;
import com.jxc.model.po.AuditRecord;
import com.jxc.model.po.Goods;
import com.jxc.model.po.Member;
import com.jxc.model.po.Repertory;
import com.jxc.model.po.Salelist;
import com.jxc.model.po.SalelistItem;
import com.jxc.model.po.User;
import com.jxc.model.vo.DataGrid;
import com.jxc.model.vo.VAuditRecord;
import com.jxc.model.vo.VSalelist;
import com.jxc.model.vo.VSalelistItem;
import com.jxc.service.SalelistServiceI;

/**
 * @author Tino
 * 
 */
@Service("salelistService")
public class SalelistServiceImpl implements SalelistServiceI {

	@Autowired
	private BaseDaoI<Salelist> salelistDao;
	@Autowired
	private BaseDaoI<SalelistItem> itemDao;
	@Autowired
	private BaseDaoI<AuditRecord> auditRecordDao;
	@Override
	public DataGrid datagridNoPage(VSalelist vSalelist) {
		DataGrid dg = new DataGrid();
		dg.setRows(this.changeModel(this.findNoPage(vSalelist)));
		return dg;
	}

	private List<Salelist> findNoPage(VSalelist vSalelist) {
		String hql = "from Salelist t where 1=1 ";

		List<Object> values = new ArrayList<Object>();
		hql = addWhere(vSalelist, hql, values);

		return salelistDao.find(hql, values);
	}

	@Override
	public List<VSalelistItem> getItems(VSalelist vSalelist) {
		String hql = "from SalelistItem t where t.refund=false";
		
		List<Object> values = new ArrayList<Object>();
		if(vSalelist.getId()!=null){
			hql +=" and t.salelist.id = ? ";
			values.add(vSalelist.getId());
		}
		if(vSalelist.getSerial()!=null){
			hql +=" and t.salelist.serial = ? ";
			values.add(vSalelist.getSerial());
		}
		List<SalelistItem> list = itemDao.find(hql, values);
		return changeModelByItem(list);
	}
	private List<VSalelistItem> changeModelByItem(List<SalelistItem> items){
		List<VSalelistItem> vItems = new ArrayList<VSalelistItem>();
		if(items!=null&&items.size()>0){
			for(SalelistItem item:items){
				VSalelistItem vItem = new VSalelistItem();
				BeanUtils.copyProperties(item, vItem);
				Goods goods = item.getGoods();
				if(goods!=null){
					vItem.setGid(goods.getId());
					vItem.setGname(goods.getName());
					vItem.setGcolor(goods.getColor());
					vItem.setGsize(goods.getSize());
				}
				vItems.add(vItem);
			}
		}
		
		
		return vItems;
	}

	@Override
	public VSalelist getSalelistById(Long id) {
		Salelist salelist = salelistDao.get(Salelist.class, id);
		if(salelist!=null){
			VSalelist vSalelist = new VSalelist();
			BeanUtils.copyProperties(salelist, vSalelist);
			User user = salelist.getUser();
			if (user != null) {
				vSalelist.setUid(user.getId());
				vSalelist.setUusername(user.getUsername());
			}
			Member member = salelist.getMember();
			if (member != null) {
				vSalelist.setMid(member.getId());
				vSalelist.setMname(member.getName());
			}
			Repertory repertory = salelist.getRepertory();
			if (repertory != null) {
				vSalelist.setRid(repertory.getId());
				vSalelist.setRname(repertory.getName());
			}
			return vSalelist;
		}else{
			return null;
		}
	}

	@Override
	public List<VSalelistItem> getItemsByIds(String ids) {
		List<SalelistItem> items = new ArrayList<SalelistItem>();
		String[] strIds = ids.split(",");
		for(String strId:strIds){
			SalelistItem item = itemDao.get(SalelistItem.class, Long.parseLong(strId));
			if(item!=null){
				items.add(item);
			}
		}
		return changeModelByItem(items);
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jxc.service.SalelistServiceI#combobox(com.jxc.model.vo.VSalelist)
	 */
	@Override
	public List<VSalelist> combobox(VSalelist vsl) {
		return this.changeModel(this.find(vsl));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jxc.service.SalelistServiceI#datagrid(com.jxc.model.vo.VSalelist)
	 */
	@Override
	public DataGrid datagrid(VSalelist vsl) {
		DataGrid dg = new DataGrid();
		dg.setRows(this.changeModel(this.find(vsl)));
		dg.setTotal(this.total(vsl));
		return dg;
	}
	
	public DataGrid datagridTotal(VSalelist vsl) {
		DataGrid dg = new DataGrid();		
		dg.setRows(this.changeModelTotal(this.findTotal(vsl),vsl));
		//dg.setTotal(this.totalTotal(vsl));
		return dg;
	}
	
	public DataGrid datagridsettlementTotal(VSalelist vsl) {
		DataGrid dg = new DataGrid();		
		dg.setRows(this.changeModelsettlementTotal(this.findsettlementTotal(vsl)));
		//dg.setTotal(this.totalsettlementTotal(vsl));
		return dg;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jxc.service.SalelistServiceI#delete(java.lang.String)
	 */
	@Override
	public void delete(String ids) {
		if (ids != null) {
			for (String id : ids.split(",")) {
				if (!id.trim().equals("0")) {
					Salelist ct = salelistDao.get(Salelist.class, Long.parseLong(id.trim()));
					if (ct != null) {
						salelistDao.delete(ct);
					}
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jxc.service.SalelistServiceI#save(com.jxc.model.vo.VSalelist)
	 */
	@Override
	public Long save(VSalelist vsl) {
		Salelist st = new Salelist();
		BeanUtils.copyProperties(vsl, st);
		if (vsl.getUid() != null) {
			st.setUser(new User(vsl.getUid()));
		}
		if (vsl.getMid() != null) {
			st.setMember(new Member(vsl.getMid()));
		}
		if (vsl.getRid() != null) {
			st.setRepertory(new Repertory(vsl.getRid()));
		}
		this.salelistDao.save(st);
		return st.getId();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jxc.service.SalelistServiceI#search(com.jxc.model.vo.VSalelist)
	 */
	@Override
	public List<VSalelist> search(VSalelist vsl) {
		List<Salelist> sls = this.find(vsl);
		for (Salelist sl : sls) {
			Hibernate.initialize(sl.getItems());
		}
		return this.changeModel(sls);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.jxc.service.SalelistServiceI#update(com.jxc.model.vo.VSalelist)
	 */
	@Override
	public void update(VSalelist vsl) {
		Salelist st = this.salelistDao.get(Salelist.class, vsl.getId());
		BeanUtils.copyProperties(vsl, st, new String[] { "id" });
		if (vsl.getUid() != null) {
			st.setUser(new User(vsl.getUid()));
		}
		if (vsl.getMid() != null) {
			st.setMember(new Member(vsl.getMid()));
		}
		if (vsl.getRid() != null) {
			st.setRepertory(new Repertory(vsl.getRid()));
		}
		this.salelistDao.update(st);
	}

	private List<VSalelist> changeModel(List<Salelist> sls) {
		List<VSalelist> vsls = new ArrayList<VSalelist>();
		if (sls != null && sls.size() > 0) {
			for (Salelist sl : sls) {
				VSalelist vsl = new VSalelist();
				BeanUtils.copyProperties(sl, vsl);
				if (sl.getUser() != null) {
					User user = sl.getUser();
					vsl.setUid(user.getId());
					vsl.setUusername(user.getUsername());
				}

				if (sl.getMember() != null) {
					Member member = sl.getMember();
					vsl.setMid(member.getId());
					vsl.setMname(member.getName());
				}

				if (sl.getRepertory() != null) {
					Repertory repertory = sl.getRepertory();
					vsl.setRid(repertory.getId());
					vsl.setRname(repertory.getName());
				}

				vsls.add(vsl);
			}
		}
		return vsls;
	}
	
	private List<VSalelist> changeModelTotal(List<Salelist> sls,VSalelist vsale) {
		List<VSalelist> vsls = new ArrayList<VSalelist>();
		
		//String beginDateStr = new SimpleDateFormat("yyyy-MM-01").format(new Date());
		//String endDateStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		//Date dateBeginstr = strToDate(beginDateStr);
		//Date dateEndStr = strToDate(endDateStr);
		Date dateBeginstr = vsale.getBeginDate();
		Date dateEndStr = vsale.getEndDate();
		  
		if (sls != null && sls.size() > 0) {
			for (Salelist sl : sls) {
				VSalelist vsl = new VSalelist();
				BeanUtils.copyProperties(sl, vsl);
				
				vsl.setBeginDate(dateBeginstr);
				vsl.setEndDate(dateEndStr);
				//vsl.setTotal(findTotalSum(sl));
				vsl.setTotal(findTotalSum(sl,vsl));
				
				if (sl.getUser() != null) {
					User user = sl.getUser();
					vsl.setUid(user.getId());
					vsl.setUusername(user.getRealName());					
				}

				if (sl.getMember() != null) {
					Member member = sl.getMember();
					vsl.setMid(member.getId());
					vsl.setMname(member.getName());					
				}

				if (sl.getRepertory() != null) {
					Repertory repertory = sl.getRepertory();
					vsl.setRid(repertory.getId());
					vsl.setRname(repertory.getName());					
				}
				vsls.add(vsl);
			}
		}
		return vsls;
	}	

	private List<VSalelist> changeModelsettlementTotal(List<AuditRecord> sls) {
		List<VSalelist> vsls = new ArrayList<VSalelist>();
		if (sls != null && sls.size() > 0) {
			for (AuditRecord sl : sls) {
				VSalelist vsl = new VSalelist();
				BeanUtils.copyProperties(sl, vsl);	
				vsl.setBeginDate(sl.getBeginAudit());
				vsl.setEndDate(sl.getEndAudit());
				if (sl.getUser() != null) {
					User user = sl.getUser();
					vsl.setUid(user.getId());
					vsl.setUusername(user.getRealName());
				}
				if (sl.getRepertory() != null) {
					Repertory repertory = sl.getRepertory();
					vsl.setRid(repertory.getId());
					vsl.setRname(repertory.getName());
				}
				vsls.add(vsl);
				/*VSalelist vsl = new VSalelist();
				BeanUtils.copyProperties(sl, vsl);				
				if (sl.getUser() != null) {
					User user = sl.getUser();
					vsl.setUid(user.getId());
					vsl.setUusername(user.getUsername());
				}
				if (sl.getRepertory() != null) {
					Repertory repertory = sl.getRepertory();
					vsl.setRid(repertory.getId());
					vsl.setRname(repertory.getName());
				}
				vsls.add(vsl);*/				
			}
		}
		return vsls;
	}	
	
	public Date strToDate(String strDate) {   
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd".trim().substring(0, 10));   
        ParsePosition pos = new ParsePosition(0);   
        Date strtodate = formatter.parse(strDate.trim().substring(0,10), pos);  
        return strtodate;   
    }
	
	
	private List<Salelist> find(VSalelist vsl) {
		String hql = "from Salelist t where 1=1 ";

		List<Object> values = new ArrayList<Object>();
		hql = addWhere(vsl, hql, values);

		if (vsl.getSort() != null && vsl.getOrder() != null) {
			hql += " order by " + vsl.getSort() + " " + vsl.getOrder();
		}
		return salelistDao.find(hql, values, vsl.getPage(), vsl.getRows());
	}
	
	private List<Salelist> findTotal(VSalelist vsl) {
		String hql = "from Salelist t where 1=1  ";
		
		List<Object> values = new ArrayList<Object>();
		hql = addWhereTotal(vsl, hql, values);
		
		hql += " GROUP BY t.user,t.repertory order by sum(t.total) DESC "; 
		return salelistDao.find(hql, values, vsl.getPage(), vsl.getRows());	
	}
	
    private Double findTotalSum(Salelist sls,VSalelist vsls) {			
		String hql = "select sum(t.total) from Salelist t where 1=1 ";
		List<Object> values = new ArrayList<Object>();
		if (sls.getRepertory() != null && sls.getUser() != null) {
			hql += " and t.repertory.id = ? and t.user.id = ? ";
			values.add(sls.getRepertory().getId());
			values.add(sls.getUser().getId());
		}
		if(vsls.getBeginDate() != null && vsls.getEndDate() != null){
			hql += " and t.date >= ? and t.date <= ? ";
			values.add(vsls.getBeginDate());
			values.add(vsls.getEndDate());
		}
		hql += " GROUP BY t.user,t.repertory order by sum(t.total) DESC  ";
		return salelistDao.countToDouble(hql, values);
	}
    
    private List<AuditRecord> findsettlementTotal(VSalelist vsl) {
		String hql = "from AuditRecord t where 1=1  ";
		
		List<Object> values = new ArrayList<Object>();
		hql = addWheresettlementTotal(vsl, hql, values);
		
		hql += " order by t.id DESC  ";
		
		return auditRecordDao.find(hql, values, vsl.getPage(), vsl.getRows());	
	}

	private Long total(VSalelist vsl) {
		String hql = "select count(*) from Salelist t where 1=1 ";
		List<Object> values = new ArrayList<Object>();
		hql = addWhere(vsl, hql, values);
		return salelistDao.count(hql, values);
	}

	private Long totalTotal(VSalelist vsl) {
		String hql = "select count(*) from Salelist t where 1=1 ";
		List<Object> values = new ArrayList<Object>();
		hql = addWhereTotal(vsl, hql, values);
		
		hql += " GROUP BY t.user,t.repertory order by sum(t.total) DESC "; 
		
		return salelistDao.count(hql, values);
	}
	
	private Long totalsettlementTotal(VSalelist vsl) {
		String hql = "select count(*) from AuditRecord t where 1=1 ";
		List<Object> values = new ArrayList<Object>();
		hql = addWheresettlementTotal(vsl, hql, values);
		return salelistDao.count(hql, values);
	}
	private String addWhere(VSalelist vsl, String hql, List<Object> values) {
		if (vsl.getId() != null) {
			hql += " and t.id = ? ";
			values.add(vsl.getId());
		}

		if (vsl.getUid() != null) {
			hql += " and t.user.id = ? ";
			values.add(vsl.getUid());
		}

		if (vsl.getMid() != null) {
			hql += " and t.member.id = ? ";
			values.add(vsl.getMid());
		}

		if (vsl.getRid() != null) {
			hql += " and t.repertory.id = ? ";
			values.add(vsl.getRid());
		}

		if (vsl.getBeginDate() != null) {
			hql += " and t.date >= ? ";
			values.add(vsl.getBeginDate());
		}

		if (vsl.getEndDate() != null) {
			hql += " and t.date <= ? ";
			values.add(vsl.getEndDate());
		}
		return hql;
	}
	
	private String addWhereTotal(VSalelist vsl, String hql, List<Object> values) {
		
		/*if (vsl.getUusername() != null) {
			hql += " and t.user.id = ? ";
			values.add(vsl.getUid());
		}*/
		
		if (vsl.getRid() != null) {
			hql += " and t.repertory.id = ? ";
			values.add(vsl.getRid());
		}

		if (vsl.getBeginDate() != null) {
			hql += " and t.date >= ? ";
			values.add(vsl.getBeginDate());
		}

		if (vsl.getEndDate() != null) {
			hql += " and t.date <= ? ";
			values.add(vsl.getEndDate());
		}
		return hql;
	}
	
    private String addWheresettlementTotal(VSalelist vsl, String hql, List<Object> values) {		
		if (vsl.getRid() != null) {
			hql += " and t.repertory.id = ? ";
			values.add(vsl.getRid());
		}

		if (vsl.getBeginDate() != null) {
			hql += " and t.beginAudit >= ? ";
			values.add(vsl.getBeginDate());
		}

		if (vsl.getEndDate() != null) {
			hql += " and t.endAudit <= ? ";
			values.add(vsl.getEndDate());
		}
		return hql;
	}

}
